﻿// Inner Fire 游戏引擎库
// Pipeline管理类
//
// Copyright (c) 2024 by 尔西大帝. All rights reserved.
//
// 这个类提供Pipeline的快捷操作。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2024-12-06

#pragma once

#include <EASTL/vector.h>
#include <dx/core/dx_core.h>
#include <dx/graphics/dx_module.h>
#include <string>
#include <unordered_map>

namespace ifire::dx {

class DxGraphics;

// 用于固定的Shader
static constexpr auto STANDARD_VS = "StandardVS";
static constexpr auto SKINNED_VS = "SkinnedVS";
static constexpr auto ALPHA_TEST_PS = "AlphaTestPS";
static constexpr auto SKINNED_ALPHA_TEST_PS = "AlphaTestPS";
static constexpr auto OPAQUE_PS = "OpaquePS";

static constexpr auto SKYBOX_VS = "SkyBoxVS";
static constexpr auto SKYBOX_PS = "SkyBoxPS";

static constexpr auto SHADOW_VS = "ShadowVS";
static constexpr auto SKINNED_SHADOW_VS = "SkinnedShadowVS";
static constexpr auto SHADOW_PS = "ShadowPS";
static constexpr auto SHADOW_DEBUG_VS = "ShadowDebugVS";
static constexpr auto SHADOW_DEBUG_PS = "ShadowDebugPS";
static constexpr auto DRAW_NORMALS_VS = "DrawNormalsVS";
static constexpr auto SKINNED_DRAW_NORMALS_VS = "SkinnedDrawNormalsVS";
static constexpr auto DRAW_NORMALS_PS = "DrawNormalsPS";
static constexpr auto SSAO_VS = "SsaoVS";
static constexpr auto SSAO_PS = "SsaoPS";
static constexpr auto SSAO_BLUR_VS = "SsaoBlurVS";
static constexpr auto SSAO_BLUR_PS = "SsaoBlurPS";

static constexpr auto TREE_SPRITE_VS = "TreeSpriteVS";
static constexpr auto TREE_SPRITE_GS = "TreeSpriteGS";
static constexpr auto TREE_SPRITE_PS = "TreeSpritePS";

static constexpr auto WAVES_VS = "WavesVS";
static constexpr auto WAVES_UPDATE_CS = "WavesUpdateCS";
static constexpr auto WAVES_DISTURB_CS = "WavesDisturbCS";
static constexpr auto COMPOSITE_VS = "CompositeVS";
static constexpr auto COMPOSITE_PS = "CompositePS";
static constexpr auto SOBEL_CS = "SobelCS";

static constexpr auto UI_IMAGE_VS = "UI_IMAGE_VS";
static constexpr auto UI_IMAGE_PS = "UI_IMAGE_PS";

static constexpr auto PARTICLE_VS = "PARTICLE_VS";
static constexpr auto PARTICLE_PS = "PARTICLE_PS";

static constexpr auto MAP_BLOCK_VS = "MAP_BLOCK_VS";
static constexpr auto MAP_BLOCK_PS = "MAP_BLOCK_PS";

static constexpr auto PARTICLE_LINE_VS = "PARTICLE_LINE_VS";
static constexpr auto PARTICLE_LINE_PS = "PARTICLE_LINE_PS";

static constexpr auto PARTICLE_MESH_VS = "PARTICLE_MESH_VS";
static constexpr auto PARTICLE_MESH_PS = "PARTICLE_MESH_PS";

class DxPipeline : public DxModule {
public:
  DxPipeline(DxGraphics* dx);
  DxPipeline(const DxPipeline& rhs) = delete;
  DxPipeline& operator=(const DxPipeline& rhs) = delete;
  ~DxPipeline() = default;

  void BuildShaderAndInputLayout(const D3D_SHADER_MACRO* debug_defines);
  void BuildPipelineStates();

  void CreateShadow();
  void CreateOpaque();
  void CreateSky();
  void CreateDebug();
  void CreateDrawNormals();
  void CreateSsao();
  void CreateTreeSprites();
  void CreateTransparent();
  void CreateComposite();
  void CreateWaves();
  void CreateSobel();
  void CreateUIImage();
  void CreateMapBlock();
  void CreateParticle();
  void CreateAlpha();

  bool IsContainShader(const char* key) const;
  bool IsContainPipeline(const char* key) const;

  ID3D12PipelineState* operator[](const char* key) const;

private:
  // 用于各类Shader的创建
  void CreateOpaqueWire();
  void CreateAlphaTest();

  eastl::vector<D3D12_INPUT_ELEMENT_DESC> input_layout_;
  eastl::vector<D3D12_INPUT_ELEMENT_DESC> skinned_input_layout_;
  eastl::vector<D3D12_INPUT_ELEMENT_DESC> tree_sprite_input_layout_;
  eastl::vector<D3D12_INPUT_ELEMENT_DESC> ui_input_layout_;
  // 用于Shader
  std::unordered_map<std::string_view, ComPtr<ID3DBlob>> shaders_;
  // 用于管线
  std::unordered_map<std::string_view, ComPtr<ID3D12PipelineState>> pipelines_;


  // 用于默认的管线
  D3D12_GRAPHICS_PIPELINE_STATE_DESC opaque_desc;
  D3D12_GRAPHICS_PIPELINE_STATE_DESC skinned_desc;
  D3D12_GRAPHICS_PIPELINE_STATE_DESC transparent_desc;

};
} // namespace ifire::dx